"""剪切板监控模块"""

import io
import time
from typing import Optional, Callable, Any
from PySide6.QtCore import QThread, QTimer, Signal, QObject, QBuffer
from PySide6.QtGui import QClipboard, QPixmap, QImage
from PySide6.QtWidgets import QApplication
from PIL import Image
import base64

from .database import ClipboardDatabase, ClipboardItem


class ClipboardMonitor(QObject):
    """剪切板监控器"""
    
    # 信号定义
    content_changed = Signal(str, str)  # content, content_type
    item_added = Signal(ClipboardItem)  # 新增项目
    
    def __init__(self, database: ClipboardDatabase):
        super().__init__()
        self.database = database
        self.clipboard = QApplication.clipboard()
        self.last_content = ""
        self.last_content_type = ""
        self.timer = QTimer()
        self.timer.timeout.connect(self.check_clipboard)
        self.monitoring = False
        
    def start_monitoring(self, interval: int = 500):
        """开始监控剪切板变化"""
        if not self.monitoring:
            self.monitoring = True
            # 获取当前剪切板内容作为初始状态
            self._update_last_content()
            self.timer.start(interval)
            print("剪切板监控已启动")
    
    def stop_monitoring(self):
        """停止监控剪切板变化"""
        if self.monitoring:
            self.monitoring = False
            self.timer.stop()
            print("剪切板监控已停止")
    
    def check_clipboard(self):
        """检查剪切板内容变化"""
        try:
            mime_data = self.clipboard.mimeData()
            content = ""
            content_type = "text"
            
            if mime_data.hasText():
                content = mime_data.text().strip()
                content_type = "text"
            elif mime_data.hasImage():
                # 处理图片
                image = self.clipboard.image()
                if not image.isNull():
                    content = self._image_to_base64(image)
                    content_type = "image"
            elif mime_data.hasUrls():
                # 处理文件路径
                urls = mime_data.urls()
                if urls:
                    paths = [url.toLocalFile() for url in urls if url.isLocalFile()]
                    if paths:
                        content = "\n".join(paths)
                        content_type = "files"
            
            # 检查内容是否发生变化
            if content and (content != self.last_content or content_type != self.last_content_type):
                self.last_content = content
                self.last_content_type = content_type
                
                # 添加到数据库
                item_id = self.database.add_item(content, content_type)
                if item_id:
                    item = self.database.get_item_by_id(item_id)
                    if item:
                        self.content_changed.emit(content, content_type)
                        self.item_added.emit(item)
                        
        except Exception as e:
            print(f"检查剪切板时发生错误: {e}")
    
    def _update_last_content(self):
        """更新最后的剪切板内容"""
        try:
            mime_data = self.clipboard.mimeData()
            if mime_data.hasText():
                self.last_content = mime_data.text().strip()
                self.last_content_type = "text"
            elif mime_data.hasImage():
                image = self.clipboard.image()
                if not image.isNull():
                    self.last_content = self._image_to_base64(image)
                    self.last_content_type = "image"
            elif mime_data.hasUrls():
                urls = mime_data.urls()
                if urls:
                    paths = [url.toLocalFile() for url in urls if url.isLocalFile()]
                    if paths:
                        self.last_content = "\n".join(paths)
                        self.last_content_type = "files"
        except Exception as e:
            print(f"更新最后内容时发生错误: {e}")
    
    def _image_to_base64(self, qimage) -> str:
        """将QImage转换为base64字符串"""
        try:
            # 直接使用QPixmap保存到字节流
            pixmap = QPixmap.fromImage(qimage)
            byte_array = io.BytesIO()
            
            # 保存为PNG格式
            buffer = QBuffer()
            buffer.open(QBuffer.WriteOnly)
            pixmap.save(buffer, "PNG")
            
            # 转换为base64
            img_data = buffer.data().data()
            img_base64 = base64.b64encode(img_data).decode('utf-8')
            return f"data:image/png;base64,{img_base64}"
            
        except Exception as e:
            print(f"图片转换错误: {e}")
            return ""
    
    def set_clipboard_content(self, content: str, content_type: str = "text"):
        """设置剪切板内容"""
        try:
            if content_type == "text":
                self.clipboard.setText(content)
            elif content_type == "image":
                # 处理base64图片
                if content.startswith("data:image"):
                    base64_data = content.split(",")[1]
                    image_data = base64.b64decode(base64_data)
                    
                    # 直接从二进制数据创建QPixmap，避免质量损失
                    pixmap = QPixmap()
                    if pixmap.loadFromData(image_data):
                        self.clipboard.setPixmap(pixmap)
                        print(f"成功复制图片到剪切板，尺寸: {pixmap.width()}x{pixmap.height()}")
                    else:
                        print("无法从数据创建图片")
            elif content_type == "files":
                # 处理文件路径（这里简化为文本处理）
                self.clipboard.setText(content)
            
            # 更新最后内容以避免重复检测
            self.last_content = content
            self.last_content_type = content_type
            
        except Exception as e:
            print(f"设置剪切板内容时发生错误: {e}")
    
    def _pil_to_qimage(self, pil_image):
        """将PIL Image转换为QImage"""
        try:
            if pil_image.mode == "RGB":
                r, g, b = pil_image.split()
                pil_image = Image.merge("RGB", (b, g, r))
            elif pil_image.mode == "RGBA":
                r, g, b, a = pil_image.split()
                pil_image = Image.merge("RGBA", (b, g, r, a))
            
            # 转换为字节数组
            im2 = pil_image.convert("RGBA")
            data = im2.tobytes("raw", "RGBA")
            
            # 创建QImage
            qimage = QImage(data, pil_image.size[0], pil_image.size[1], QImage.Format_RGBA8888)
            return qimage
            
        except Exception as e:
            print(f"PIL转QImage错误: {e}")
            return QImage()


class ClipboardUtils:
    """剪切板工具类"""
    
    @staticmethod
    def get_content_preview(content: str, content_type: str, max_length: int = 100) -> str:
        """获取内容预览"""
        if content_type == "text":
            # 处理文本内容
            preview = content.replace('\n', ' ').replace('\r', ' ')
            if len(preview) > max_length:
                preview = preview[:max_length] + "..."
            return preview
        elif content_type == "image":
            return "[图片]"
        elif content_type == "files":
            lines = content.split('\n')
            if len(lines) == 1:
                return f"[文件] {lines[0]}"
            else:
                return f"[{len(lines)}个文件] {lines[0]}..."
        else:
            return "[未知类型]"
    
    @staticmethod
    def format_size(size_bytes: int) -> str:
        """格式化文件大小"""
        if size_bytes < 1024:
            return f"{size_bytes} B"
        elif size_bytes < 1024 * 1024:
            return f"{size_bytes / 1024:.1f} KB"
        elif size_bytes < 1024 * 1024 * 1024:
            return f"{size_bytes / (1024 * 1024):.1f} MB"
        else:
            return f"{size_bytes / (1024 * 1024 * 1024):.1f} GB"
    
    @staticmethod
    def get_content_type_icon(content_type: str) -> str:
        """获取内容类型图标"""
        icons = {
            "text": "📝",
            "image": "🖼️",
            "files": "📁"
        }
        return icons.get(content_type, "❓") 